/**
 * 
 */
package com.fnic.pearl.scheduler;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang.StringUtils;

/**
 * 调度器配置信息，加载 scheduler.properties
 * 
 * @author HuHaiyang
 * @date 2013年7月14日
 */
public class SchedulerConfig
{

    /**
     * singleton access
     */
    private static SchedulerConfig instance = new SchedulerConfig();

    public static SchedulerConfig getInstance()
    {
        return instance;
    }

    // 配置文件路径
    public static final String CONF_FILE = "scheduler.properties";

    // ---------- common ---------

    // 本调度器节点标识
    private int schedulerId = 0;

    public static final String KEY_SCHEDULER_ID = "common.scheduler.id";

    // 心跳超时等待时长
    private long hbTimeout = 120;

    public static final String KEY_PROBE_HB_TIMEOUT = "common.probe.hb.timeout";

    // 最大单次测量任务下发数
    private int maxTestTaskNum = 20;

    public static final String KEY_PROBE_TESTASK_MAXNUM = "common.probe.testask.maxnum";

    // 最大单次可上报的任务状态记录数
    private int maxTTSNum = 20;

    public static final String KEY_PROBE_TTS_MAXNUM = "common.manager.tts.maxnum";

    // 是否需要对下发任务进行加密
    private boolean encryptTestTask = false;

    public static final String KEY_PROBE_TESTASK_ENCRYPT = "common.probe.testask.encrypt";

    // 检测与 probe 之间的连接超时时长
    private long probeCheckTimeout = 30;

    public static final String KEY_PROBE_CHECK_TIMEOUT = "common.probe.check.timeout";

    // ------------- scheduler 作为服务端 ---------
    // 链路最大空闲时长，单位：秒
    private int idleTimeout = 3600;

    // --------------- request log -----------------
    // 请求日志文件名
    private String requestLogFileName = "./logs/request.log";

    public static final String KEY_REQ_LOG_FILENAME = "server.reqlog.filename";

    // 请求日志保存的时长，单位：天
    private int retainDays = 90;

    public static final String KEY_REQ_LOG_RETAIN = "server.reqlog.retain";

    // 请求日志时区
    private String requestLogTimezone = "GMT+8";

    public static final String KEY_REQ_LOG_TIMEZONE = "server.reqlog.timeZone";

    // 请求日志的时间格式
    private String requestLogDateFormat = "yyyy-MM-dd HH:mm:ss";

    public static final String KEY_REQ_LOG_DATE_FMT = "server.reqlog.dateFormat";

    // ---------------- manager ----------------
    // 管理节点监听地址与端口
    private String managerIp = "192.168.28.64";

    private short managerPort = 8080;// MsgDvier端口
    // 一部分在管理节点中

    private long managerTimeout = 5;

    public static final String KEY_MANAGER_HTTP_IP = "client.manager.http.ip";

    public static final String KEY_MANAGER_HTTP_PORT = "client.manager.http.port";

    public static final String KEY_MANAGER_HTTP_TIMEOUT = "client.manager.http.timeout";

    public static final String KEY_MANAGER_HTTP_MANAGERPORT = "client.manager.http.managerPort";

    // t_info_scheduler 调度器登录时，数据库填充字段
    public static final String INFO_SCHEDULER_INNERIP = "t_info_scheduler.innerIp";

    public static final String INFO_SCHEDULER_INNERPORT = "t_info_scheduler.innerPort";

    public static final String INFO_SCHEDULER_IP = "t_info_scheduler.ip";

    public static final String INFO_SCHEDULER_PORT = "t_info_scheduler.port";

    public static final String SCHEDULER_DOMAIN = "scheduler.domain";

    public String infoSchedulerInnerIp;

    public String infoSchedulerInnerPort;

    public String infoSchedulerIp;

    public String infoSchedulerPort;

    public String schedulerDomain;

    // ---------------- redis ----------------
    private boolean redisEnable = false;

    public static final String KEY_REDIS_ENABLE = "redis.enable";

    private String redisMasterIp = "127.0.0.1";

    public static final String KEY_REDIS_MASTER_IP = "redis.master.ip";

    private int redisMasterPort = 6379;

    public static final String KEY_REDIS_MASTER_PORT = "redis.master.port";

    private int redisMasterTimeout = 300;

    public static final String KEY_REDIS_MASTER_TIMEOUT = "redis.master.timeout";

    private String redisSlaveIp = "127.0.0.1";

    private static final String KEY_REDIS_SLAVE_IP = "redis.slave.ip";

    private int redisSlavePort = 6380;

    private static final String KEY_REDIS_SLAVE_PORT = "redis.slave.port";

    private int redisSlaveTimeout = 300;

    public static final String KEY_REDIS_SLAVE_TIMEOUT = "redis.slave.timeout";

    // ---------------- develop/debug ----------------

    /**
     * 加载 scheduler 的配置
     * 
     * @throws ConfigurationException cex
     */
    public void load() throws ConfigurationException
    {
        PropertiesConfiguration config = new PropertiesConfiguration(CONF_FILE);
        schedulerId = Integer.parseInt((String) config.getProperty(KEY_SCHEDULER_ID));
        hbTimeout = Long.parseLong((String) config.getProperty(KEY_PROBE_HB_TIMEOUT));
        probeCheckTimeout = Long.parseLong((String) config.getProperty(KEY_PROBE_CHECK_TIMEOUT));
        maxTestTaskNum = Integer.parseInt((String) config.getProperty(KEY_PROBE_TESTASK_MAXNUM));
        maxTTSNum = Integer.parseInt((String) config.getProperty(KEY_PROBE_TTS_MAXNUM));
        // encryptTestTask = Integer.parseInt((String) config
        // .getProperty(KEY_PROBE_TESTASK_ENCRYPT)) > 0 ? true : false;
        requestLogFileName = (String) config.getProperty(KEY_REQ_LOG_FILENAME);
        retainDays = Integer.parseInt((String) config.getProperty(KEY_REQ_LOG_RETAIN));
        requestLogTimezone = (String) config.getProperty(KEY_REQ_LOG_TIMEZONE);
        requestLogDateFormat = (String) config.getProperty(KEY_REQ_LOG_DATE_FMT);
        managerIp = (String) config.getProperty(KEY_MANAGER_HTTP_IP);
        managerPort = Short.parseShort((String) config.getProperty(KEY_MANAGER_HTTP_PORT));
        managerTimeout = Long.parseLong((String) config.getProperty(KEY_MANAGER_HTTP_TIMEOUT));
        redisEnable = config.getBoolean(KEY_REDIS_ENABLE);
        redisMasterIp = (String) config.getProperty(KEY_REDIS_MASTER_IP);
        redisMasterPort = Integer.parseInt((String) config.getProperty(KEY_REDIS_MASTER_PORT));
        redisMasterTimeout = Integer.parseInt((String) config.getProperty(KEY_REDIS_MASTER_TIMEOUT));
        redisSlaveIp = (String) config.getProperty(KEY_REDIS_SLAVE_IP);
        redisSlavePort = Integer.parseInt((String) config.getProperty(KEY_REDIS_SLAVE_PORT));
        redisSlaveTimeout = Integer.parseInt((String) config.getProperty(KEY_REDIS_SLAVE_TIMEOUT));
        // t_info_scheduler 调度器登录时，数据库填充字段
        infoSchedulerInnerIp = (String) config.getProperty(INFO_SCHEDULER_INNERIP);
        infoSchedulerInnerPort = (String) config.getProperty(INFO_SCHEDULER_INNERPORT);
        infoSchedulerIp = (String) config.getProperty(INFO_SCHEDULER_IP);
        infoSchedulerPort = (String) config.getProperty(INFO_SCHEDULER_PORT);
        schedulerDomain = (String) config.getProperty(SCHEDULER_DOMAIN);
    }

    /**
     * @return the schedulerId
     */
    public int getSchedulerId()
    {
        return schedulerId;
    }

    /**
     * @param schedulerId the schedulerId to set
     */
    public void setSchedulerId(int schedulerId)
    {
        this.schedulerId = schedulerId;
    }

    /**
     * @return the hbTimeout
     */
    public long getHbTimeout()
    {
        return hbTimeout;
    }

    /**
     * @param hbTimeout the hbTimeout to set
     */
    public void setHbTimeout(long hbTimeout)
    {
        this.hbTimeout = hbTimeout;
    }

    /**
     * @return the maxTestTaskNum
     */
    public int getMaxTestTaskNum()
    {
        return maxTestTaskNum;
    }

    /**
     * @param maxTestTaskNum the maxTestTaskNum to set
     */
    public void setMaxTestTaskNum(int maxTestTaskNum)
    {
        this.maxTestTaskNum = maxTestTaskNum;
    }

    /**
     * @return the maxTTSNum
     */
    public int getMaxTTSNum()
    {
        return maxTTSNum;
    }

    /**
     * @param maxTTSNum the maxTTSNum to set
     */
    public void setMaxTTSNum(int maxTTSNum)
    {
        this.maxTTSNum = maxTTSNum;
    }

    // /**
    // * @return the encryptTestTask
    // */
    // public boolean isEncryptTestTask()
    // {
    // return encryptTestTask;
    // }
    //
    // /**
    // * @param encryptTestTask the encryptTestTask to set
    // */
    // public void setEncryptTestTask(boolean encryptTestTask)
    // {
    // this.encryptTestTask = encryptTestTask;
    // }

    /**
     * @return the idleTimeout
     */
    public int getIdleTimeout()
    {
        return idleTimeout;
    }

    /**
     * @param idleTimeout the idleTimeout to set
     */
    public void setIdleTimeout(int idleTimeout)
    {
        this.idleTimeout = idleTimeout;
    }

    /**
     * @return the requestLogFileName
     */
    public String getRequestLogFileName()
    {
        return requestLogFileName;
    }

    /**
     * @param requestLogFileName the requestLogFileName to set
     */
    public void setRequestLogFileName(String requestLogFileName)
    {
        this.requestLogFileName = requestLogFileName;
    }

    /**
     * @return the retainDays
     */
    public int getRetainDays()
    {
        return retainDays;
    }

    /**
     * @param retainDays the retainDays to set
     */
    public void setRetainDays(int retainDays)
    {
        this.retainDays = retainDays;
    }

    /**
     * @return the probeCheckTimeout
     */
    public long getProbeCheckTimeout()
    {
        return probeCheckTimeout;
    }

    /**
     * @param probeCheckTimeout the probeCheckTimeout to set
     */
    public void setProbeCheckTimeout(long probeCheckTimeout)
    {
        this.probeCheckTimeout = probeCheckTimeout;
    }

    /**
     * @return the requestLogTimezone
     */
    public String getRequestLogTimezone()
    {
        return requestLogTimezone;
    }

    /**
     * @param requestLogTimezone the requestLogTimezone to set
     */
    public void setRequestLogTimezone(String requestLogTimezone)
    {
        this.requestLogTimezone = requestLogTimezone;
    }

    /**
     * @return the requestLogDateFormat
     */
    public String getRequestLogDateFormat()
    {
        return requestLogDateFormat;
    }

    /**
     * @param requestLogDateFormat the requestLogDateFormat to set
     */
    public void setRequestLogDateFormat(String requestLogDateFormat)
    {
        this.requestLogDateFormat = requestLogDateFormat;
    }

    /**
     * @return the managerIp
     */
    public String getManagerIp()
    {
        return managerIp;
    }

    /**
     * @param managerIp the managerIp to set
     */
    public void setManagerIp(String managerIp)
    {
        this.managerIp = managerIp;
    }

    /**
     * @return the managerTimeout
     */
    public long getManagerTimeout()
    {
        return managerTimeout;
    }

    /**
     * @param managerTimeout the managerTimeout to set
     */
    public void setManagerTimeout(long managerTimeout)
    {
        this.managerTimeout = managerTimeout;
    }

    /**
     * @return the redisSlaveIp
     */
    public String getRedisSlaveIp()
    {
        return redisSlaveIp;
    }

    /**
     * @return the redisEnable
     */
    public boolean isRedisEnable()
    {
        return redisEnable;
    }

    /**
     * @param redisEnable the redisEnable to set
     */
    public void setRedisEnable(boolean redisEnable)
    {
        this.redisEnable = redisEnable;
    }

    /**
     * @param redisSlaveIp the redisSlaveIp to set
     */
    public void setRedisSlaveIp(String redisSlaveIp)
    {
        this.redisSlaveIp = redisSlaveIp;
    }

    /**
     * @return the redisSlavePort
     */
    public int getRedisSlavePort()
    {
        return redisSlavePort;
    }

    /**
     * @param redisSlavePort the redisSlavePort to set
     */
    public void setRedisSlavePort(int redisSlavePort)
    {
        this.redisSlavePort = redisSlavePort;
    }

    /**
     * @return the redisSlaveTimeout
     */
    public int getRedisSlaveTimeout()
    {
        return redisSlaveTimeout;
    }

    /**
     * @param redisSlaveTimeout the redisSlaveTimeout to set
     */
    public void setRedisSlaveTimeout(int redisSlaveTimeout)
    {
        this.redisSlaveTimeout = redisSlaveTimeout;
    }

    /**
     * @return the managerPort
     */
    public short getManagerPort()
    {
        return managerPort;
    }

    /**
     * @param managerPort the managerPort to set
     */
    public void setManagerPort(short managerPort)
    {
        this.managerPort = managerPort;
    }

    /**
     * @return the redisMasterIp
     */
    public String getRedisMasterIp()
    {
        return redisMasterIp;
    }

    /**
     * @return the redisMasterTimeout
     */
    public int getRedisMasterTimeout()
    {
        return redisMasterTimeout;
    }

    /**
     * @param redisMasterTimeout the redisMasterTimeout to set
     */
    public void setRedisMasterTimeout(int redisMasterTimeout)
    {
        this.redisMasterTimeout = redisMasterTimeout;
    }

    /**
     * @param redisMasterIp the redisMasterIp to set
     */
    public void setRedisMasterIp(String redisMasterIp)
    {
        this.redisMasterIp = redisMasterIp;
    }

    /**
     * @return the redisMasterPort
     */
    public int getRedisMasterPort()
    {
        return redisMasterPort;
    }

    /**
     * @param redisMasterPort the redisMasterPort to set
     */
    public void setRedisMasterPort(int redisMasterPort)
    {
        this.redisMasterPort = redisMasterPort;
    }

    public String getInfoSchedulerInnerIp()
    {
        return infoSchedulerInnerIp;
    }

    public void setInfoSchedulerInnerIp(String infoSchedulerInnerIp)
    {
        this.infoSchedulerInnerIp = infoSchedulerInnerIp;
    }

    public String getInfoSchedulerInnerPort()
    {
        return infoSchedulerInnerPort;
    }

    public void setInfoSchedulerInnerPort(String infoSchedulerInnerPort)
    {
        this.infoSchedulerInnerPort = infoSchedulerInnerPort;
    }

    public String getInfoSchedulerIp()
    {
        return infoSchedulerIp;
    }

    public void setInfoSchedulerIp(String infoSchedulerIp)
    {
        this.infoSchedulerIp = infoSchedulerIp;
    }

    public String getInfoSchedulerPort()
    {
        return infoSchedulerPort;
    }

    public void setInfoSchedulerPort(String infoSchedulerPort)
    {
        this.infoSchedulerPort = infoSchedulerPort;
    }

    public String getSchedulerDomain()
    {
        return schedulerDomain;
    }

    public void setSchedulerDomain(String schedulerDomain)
    {
        this.schedulerDomain = schedulerDomain;
    }

    public void writeProperty(String key, String value) throws ConfigurationException
    {
        if (StringUtils.isNotBlank(value) && !StringUtils.equals(value, "0"))
        {
            PropertiesConfiguration config = new PropertiesConfiguration(CONF_FILE);
            config.setProperty(key, value);
            config.save();
            load();
        }
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        builder.append("SchedulerConfig [schedulerId=").append(schedulerId).append(", hbTimeout=").append(hbTimeout)
                .append(", maxTestTaskNum=").append(maxTestTaskNum).append(", maxTTSNum=").append(maxTTSNum)
                .append(", encryptTestTask=").append(encryptTestTask).append(", probeCheckTimeout=")
                .append(probeCheckTimeout).append(", idleTimeout=").append(idleTimeout).append(", requestLogFileName=")
                .append(requestLogFileName).append(", retainDays=").append(retainDays).append(", requestLogTimezone=")
                .append(requestLogTimezone).append(", requestLogDateFormat=").append(requestLogDateFormat)
                .append(", managerIp=").append(managerIp).append(", managerPort=").append(managerPort)
                .append(", managerTimeout=").append(managerTimeout).append(", redisEnable=").append(redisEnable)
                .append(", redisMasterIp=").append(redisMasterIp).append(", redisMasterPort=").append(redisMasterPort)
                .append(", redisMasterTimeout=").append(redisMasterTimeout).append(", redisSlaveIp=")
                .append(redisSlaveIp).append(", redisSlavePort=").append(redisSlavePort).append(", redisSlaveTimeout=")
                .append(redisSlaveTimeout).append(", infoSchedulerInnerIp=").append(infoSchedulerInnerIp)
                .append(", infoSchedulerInnerPort=").append(infoSchedulerInnerPort).append(", infoSchedulerIp=")
                .append(infoSchedulerIp).append(", infoSchedulerPort=").append(infoSchedulerPort).append("]");
        return builder.toString();
    }

    public static void main(String[] args) throws ConfigurationException
    {
        // SchedulerConfig.getInstance().writeProperty(KEY_SCHEDULER_ID, "56");
        SchedulerConfig.getInstance().load();
        System.out.println(SchedulerConfig.getInstance().getSchedulerId());
    }
}
